/**
 * @file        projects.hpp
 * @brief       Defines methods related with projects.
 *
 * @author      Emre Turkay <emreturkay at gmail>
 * @date        Jun.03.2008
 *
 * Copyright Emre Turkay 2009
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file COPYRIGHT or copy at
 * http://www.boost.org/LICENSE_1_0.txt)
 */

#ifndef _PROJECTS_HPP_
#define _PROJECTS_HPP_

#include "unique_id_container.hpp"

#include <set>
#include <list>
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>

#include <boost/optional.hpp>

namespace gtd
{

/// Holds information about an action.
struct action
{
    /// Default constructor.
    action()
    {
    }

    /// Creates an action with the given description and context set.
    action(const std::string& desc, const std::set<std::string>& ctx)
        : description_(desc),
          contexts_(ctx)
    {
    }

    /// Returns action description.
    const std::string& description() const
    {
        return description_;
    }

    /// Returns contexts.
    const std::set<std::string>& contexts() const
    {
        return contexts_;
    }

private:
    /// Action description.
    std::string description_;
    /// Action contexts.
    std::set<std::string> contexts_;
};

/// Holds the information about a project.
struct project
{
    /// Actions container data type.
    typedef unique_id_container<action> actions;
    /// Action id data type.
    typedef actions::id_type action_id;

    /// Default constructor.
    project();

    /// Construct a project with the given project name.
    project(const std::string& name);

    /// Returns the project name, if there is one.
    const boost::optional<std::string>& name() const;

    /// Prepends an action to the action list.
    void prepend(const action& item);

    /// Appends an action to the action list.
    void append(const action& item);

    /// Erases an action from the action list.
    void erase(action_id index);

    /// Returns true if the action list is empty.
    bool empty() const;

    /// Returns the number of actions.
    size_t item_count() const;

    /// Returns the action ids in order.
    std::list<action_id> items() const;

    /// Returns a specific action.
    const action& item(action_id index) const;

    /// Returns the topmost action.
    action_id top() const;

private:
    /// The project name, if there is one.
    boost::optional<std::string> name_;
    /// The actions container.
    unique_id_container<action> actions_;
};

} // namespace gtd

#include "projects.ipp"

#endif // _PROJECTS_HPP_
